#!/bin/sh

revision="add FEC's v0.3.6 (2023-07-09 by Duke, MIBonk & MIB-Wiki)"
# use --help for more info

export PATH=:/proc/boot:/sbin:/bin:/usr/bin:/usr/sbin:/net/mmx/bin:/net/mmx/usr/bin:/net/mmx/usr/sbin:/net/mmx/sbin:/net/mmx/mnt/app/armle/bin:/net/mmx/mnt/app/armle/sbin:/net/mmx/mnt/app/armle/usr/bin:/net/mmx/mnt/app/armle/usr/sbin
export LD_LIBRARY_PATH=/net/mmx/mnt/app/root/lib-target:/net/mmx/mnt/eso/lib:/net/mmx/eso/lib:/net/mmx/mnt/app/usr/lib:/net/mmx/mnt/app/armle/lib:/net/mmx/mnt/app/armle/lib/dll:/net/mmx/mnt/app/armle/usr/lib
export IPL_CONFIG_DIR=/etc/eso/production

thisname="$(basename $0)"
thisdir="$(dirname $0)"

if [ -z $LOG ]; then
	. $thisdir/../config/GLOBALS
	echo -ne "\n$ME-$thisname---->\n" >> $LOG
fi

if [ -f $TMP/reboot.mib ]; then
	echo "Reboot running..."
	return 2> /dev/null
fi

MIBCAP=3
. $thisdir/../config/MIBCHECK

ADDFECSELECT ()
{
	addFec=$VOLUME/common/tools/addFecs.txt
	if [[ ! -f $addFec ]]; then
		addFec=$VOLUME/patches/$TRAINVERSION"_"$MUVERSION"_PATCH"/addFecs.txt
		if [[ ! -f $addFec ]]; then
			MODEL=$(echo "$TRAINVERSION" | cut -d "_" -f 1 | head -c 4)
			REGION=$(echo "$TRAINVERSION" | cut -d "_" -f 2)
			BRAND=$(echo "$TRAINVERSION" | cut -d "_" -f 3 | head -c 2)
			addFec=$VOLUME/patches/addFec/$MODEL/$BRAND/$REGION/addFecs.txt
			if [[ ! -f $addFec ]]; then
				echo -ne "--- Train: $TRAINVERSION" | $TEE -a $LOG
				echo -ne "--- $addFec not found!\nStopping here....\n" | $TEE -a $LOG
				exit 1
			fi
		fi
	fi
	echo -ne "--- Found $addFec\n    Adding following FECs:\n" | $TEE -a $LOG
	cat $addFec | $TEE -a $LOG
	echo -ne "--- Train: $TRAINVERSION\n" | $TEE -a $LOG
	#remove CR EOL from addFecs.txt
	$SED 's/\r//g' $addFec > $TMP/addFecs.txt
	addFec=$TMP/addFecs.txt
}

#-----------------------------------------------------------------------------

ParseFecs ()
{
	if [ -s $BACKUPFOLDER/FEC/FecContainer.fec ];then # -s checks for file and if it is not 0 bytes
		$XXD -u -p -c 99999 $BACKUPFOLDER/FEC/FecContainer.fec > $TMP/FecContainer.tmp
		VCRNVIN=$($DD if=$TMP/FecContainer.tmp skip=14 bs=2 count=23 2> /dev/null)
		echo -ne "\n--- Using /backup/FEC/FecContainer.fec\n" | $TEE -a $LOG
	elif [ -s /net/rcc/mnt/efs-persist/FEC/FecContainer.fec ]; then
		$XXD -u -p -c 99999 /net/rcc/mnt/efs-persist/FEC/FecContainer.fec > $TMP/FecContainer.tmp
		VCRNVIN=$($DD if=$TMP/FecContainer.tmp skip=14 bs=2 count=23 2> /dev/null)
		echo -ne "\n--- Using /net/rcc/mnt/efs-persist/FEC/FecContainer.fec\n" | $TEE -a $LOG
	elif [ -s /net/rcc/mnt/efs-system/backup/FEC/FecContainer.fec ]; then
		$XXD -u -p -c 99999 /net/rcc/mnt/efs-system/backup/FEC/FecContainer.fec > $TMP/FecContainer.tmp
		VCRNVIN=$($DD if=$TMP/FecContainer.tmp skip=14 bs=2 count=23 2> /dev/null)
		echo -ne "\n--- /net/rcc/mnt/efs-system/backup/FEC/FecContainer.fec\n" | $TEE -a $LOG
	else
		echo -ne "\n--- FecContainer.fec not found. Generating a new one...\n" | $TEE -a $LOG
		[ ! -s $BACKUPFOLDER/FEC/FecContainer.fec ] && rm -f $BACKUPFOLDER/FEC/FecContainer.fec # remove 0 byte FecContainer.fec
		CreateFec
	fi

	FecCheck=$($DD if=$TMP/FecContainer.tmp skip=8 bs=2 count=2 2> /dev/null)
	if [[ $FecCheck -ne 1102 ]] && [[ $FecCheck -ne 1107 ]]; then
		echo -ne "\n--- Invalid FecContainer.fec. Generating a new one...\n" | $TEE -a $LOG
		rm $TMP/FecContainer.tmp
		CreateFec
	fi

	Pointer=0
	FecsParsed=0
	FECCOUNTHEX=$($DD if=$TMP/FecContainer.tmp skip=$Pointer bs=2 count=1 2> /dev/null)
	FECCOUNTDEC=$(echo $((0x$FECCOUNTHEX)))
	((Pointer=Pointer+8))
	while [ $FECCOUNTDEC -ne 0 ]; do
		ParseFecContainer
		((FecsParsed=FecsParsed+1))
	done
	echo -ne "--- Existing FecContainer parsed\n" | $TEE -a $LOG
}

ParseFecContainer ()
{
	if [[ $($DD if=$TMP/FecContainer.tmp skip=$Pointer bs=2 count=2 2> /dev/null) = "1102" ]]; then
		ParseSingleFec
	elif [[ $($DD if=$TMP/FecContainer.tmp skip=$Pointer bs=2 count=2 2> /dev/null) = "1107" ]]; then
		ParseMultiFec
	else
		FECCOUNTDEC=0
		FECCOUNTHEX=$(echo "ibase=10;obase=16;$FecsParsed" | $BC)
	fi
}

ParseSingleFec ()
{
	((Pointer=Pointer+2))
	if [ -f $TMP/installedFecs.tmp ]; then
		echo -n , >> $TMP/installedFecs.tmp
	fi
	$DD if=$TMP/FecContainer.tmp skip=$Pointer bs=2 count=4 >> $TMP/installedFecs.tmp 2> /dev/null
	((Pointer=Pointer+193))
	((FECCOUNTDEC=FECCOUNTDEC-1))
}

ParseMultiFec ()
{
	((Pointer=Pointer+34))
	FecAmountHEX=$($DD if=$TMP/FecContainer.tmp skip=$Pointer bs=2 count=1 2> /dev/null)
	FecAmountDEC=$(echo $((0x$FecAmountHEX)))
	FecLength=$((FecAmountDEC*4))
	((Pointer=Pointer+1))
	while [ $FecAmountDEC -ne 0 ]; do
		if [ -f $TMP/installedFecs.tmp ]; then
			echo -n , >> $TMP/installedFecs.tmp
		fi
	$DD if=$TMP/FecContainer.tmp skip=$Pointer bs=2 count=4 >> $TMP/installedFecs.tmp 2> /dev/null
	((Pointer=Pointer+4))
	((FecAmountDEC=FecAmountDEC-1))
	done
	((Pointer=Pointer+148+FecLength))
	((FECCOUNTDEC=FECCOUNTDEC-1))
}

CreateFec ()
{
	FECCOUNTHEX=0
	VCRN=03FFFFFFFFFF
	VIN=$VINCAR
	if [ -z "$VIN" ]; then
		VIN=$(cat $TMP/VIN.txt 2> /dev/null | grep VIN | $SED 's/VIN: //g' | $SED -e 's|["'\'']||g' | $SED 's/\r//')
	fi
	if [ -z "$VIN" ]; then
		VIN=MIB123456789MAGIC
	fi
	VIN=$(echo -ne $VIN | $XXD -u -p -s 0 -l 17)
	VCRNVIN=$VCRN$VIN
	read -r FEC < $addFec
	BuildFec
	$XXD -u -p -c 99999 $TMP/AddedFecs.tmp > $TMP/Fec.tmp
	echo -n "01000000" >> $TMP/FecContainer.tmp
	cat $TMP/Fec.tmp >> $TMP/FecContainer.tmp
	rm $TMP/Fec.tmp
	rm $TMP/AddedFecs.tmp
}

BuildFec ()
{
	FECCOUNTHEX=$(echo "obase=ibase=16; $FECCOUNTHEX +1" | $BC)
	while [ ${#FECCOUNTHEX} -lt 2 ]; do
		FECCOUNTHEX="0"$FECCOUNTHEX
	done
	Date=$(on -f rcc date -t 2> /dev/null)
	Epoch=$(echo -n "obase=16; ibase=10; $Date" | $BC)
	while [ ${#Epoch} -lt 8 ]; do
		Epoch="0"$Epoch
	done
	while [ ${#SIGNATURE} -ne 256 ]; do
		SIGNATURE="FF"$SIGNATURE
	done
	while [ ${#VCRNVIN} -ne 46 ]; do
		VCRNVIN=$VCRNVIN"20"
	done
	FECu=$(echo -n $FEC | $XXD -r -p | $DD conv=swab 2> /dev/null | $XXD -p -l 2)
	FECl=$(echo -n $FEC | $XXD -r -p | $DD conv=swab 2> /dev/null | $XXD -p -l 2 -s 2)
	FECLE=$FECl$FECu
	echo -n "AB0000001102"$FEC$VCRNVIN"00"$Epoch"000000000000000000"$SIGNATURE"01000000"$FECLE"0100000003000000FF000000" | $XXD -r -p >> $TMP/AddedFecs.tmp

}

BuildFecContainer ()
{
	touch $TMP/AddedFecs.tmp
	ParseFecs
	if [ -f $addFec ];then
		while read FEC; do
			FECCOUNT=$(echo $((0x$FECCOUNTHEX)))
			grep -iq $FEC $TMP/installedFecs.tmp
			FecNotPresent=$(echo $?)
			(( 16#$FEC )) > /dev/null 2>&1
			FecIsHex=$(echo $?)
			if [[ $FecIsHex -eq 0 ]] && [[ ${#FEC} -eq 8 ]] && [[ $FecNotPresent -eq 1 ]] && [[ $FECCOUNT -le 254 ]]; then
				BuildFec #creating AddedFecs.tmp
			fi
		done < $addFec
		if [ -f $TMP/AddedFecs.tmp ];then
			echo -ne "--- AddedFecs.tmp is generated.\n" | $TEE -a $LOG
			echo -n $FECCOUNTHEX"000000" | $XXD -r -p > $TMP/FecContainer.fec
			cat $TMP/AddedFecs.tmp >> $TMP/FecContainer.fec
			$DD if=$TMP/FecContainer.tmp skip=4 bs=2 2> /dev/null | $XXD -r -p >> $TMP/FecContainer.fec
			echo -ne "--- FecContainer.fec is generated.\n" | $TEE -a $LOG
			echo -ne "--- Copying /tmp/FecContainer.fec to /net/rcc/mnt/efs-persist/FEC/" | $TEE -a $LOG
			[ -n "$GEM" ] && echo -ne "\n"
			cp -rf $TMP/FecContainer.fec /net/rcc/mnt/efs-persist/FEC/ 2>> $LOG
			ERROR
		else
			echo -ne "!!! Generation of AddedFecs.tmp failed!\n\n" | $TEE -a $LOG
		fi
	else
		echo -ne "!!! Cannot generate AddedFecs.tmp as addFecs.txt is missing!\n\n" | $TEE -a $LOG
	fi
	rm $TMP/*.tmp
}

#-----------------------------------------------------------------------------

	case $1 in

-a) {

	trap '' 2

		ADDFECSELECT

		BuildFecContainer

	trap 2

	return 2> /dev/null

};;

-l) {

	trap '' 2

		FECPOINTER ()
		{
			Pointer=0
			FecsParsed=0
			FECCOUNTHEX=$($DD if=$TMP/FecContainer.tmp skip=$Pointer bs=2 count=1 2> /dev/null)
			FECCOUNTDEC=$(echo $((0x$FECCOUNTHEX)))
			((Pointer=Pointer+8))
			while [ $FECCOUNTDEC -ne 0 ]; do
				ParseFecContainer
				((FecsParsed=FecsParsed+1))
			done
		}

		rm $TMP/*.tmp 2> /dev/null
		if [ -f /net/rcc/mnt/efs-system/backup/FEC/FecContainer.fec ]; then
			echo -ne "--- Stock FECs from /net/rcc/mnt/efs-system/backup/FEC/FecContainer.fec\n" | $TEE -a $LOG
			$XXD -u -p -c 99999 /net/rcc/mnt/efs-system/backup/FEC/FecContainer.fec > $TMP/FecContainer.tmp
			VCRNVIN=$($DD if=$TMP/FecContainer.tmp skip=14 bs=2 count=23 2> /dev/null)
			FECPOINTER
			ParseFecContainer
			FECLIST=$(echo $(cat $TMP/installedFecs.tmp))
			echo -ne $FECLIST | $SED -r 's/,/\n/g' 2> /dev/null | $TEE -a $LOG
			echo -ne "\n\n" | $TEE -a $LOG
		else
			echo -ne "\n/net/rcc/mnt/efs-system/backup/FEC/FecContainer.fec not found\n" | $TEE -a $LOG
		fi

		rm $TMP/*.tmp 2> /dev/null
		if [ -f /net/rcc/mnt/efs-persist/FEC/FecContainer.fec ]; then
			echo -ne "--- FECs in use from /net/rcc/mnt/efs-persist/FEC/FecContainer.fec:\n" | $TEE -a $LOG
			$XXD -u -p -c 99999 /net/rcc/mnt/efs-persist/FEC/FecContainer.fec > $TMP/FecContainer.tmp
			VCRNVIN=$($DD if=$TMP/FecContainer.tmp skip=14 bs=2 count=23 2> /dev/null)
			FECPOINTER
			ParseFecContainer
			FECLIST=$(echo $(cat $TMP/installedFecs.tmp))
			echo -ne $FECLIST | $SED -r 's/,/\n/g' 2> /dev/null | $TEE -a $LOG
			echo -ne "\n\n" | $TEE -a $LOG
			
		else
			echo -ne "\n/net/rcc/mnt/efs-persist/FEC/FecContainer.fec not found.\n" | $TEE -a $LOG
		fi

	trap 2

	return 2> /dev/null

};;

	# help or unknown parameter ------------------------------
	*) {
		echo ""
		echo $revision
		echo ""
		echo "Usage: "$thisname" [OPTION]"
		echo ""
		echo "Options:"
		echo "        -a 			add FECs"
		echo "        -l 			list installed FECs"
		echo "        --help			show this help"
		echo ""
		echo "Note: Backup will only work in RCC bash!"
		echo ""
		echo "This program is free software; you can redistribute it and/or"
		echo "modify it under the terms of the GNU General Public License"
		echo "as published by the Free Software Foundation; either version 2"
		echo "of the License, or (at your option) any later version."
		echo ""
		echo "This program is distributed in the hope that it will be useful,"
		echo "but WITHOUT ANY WARRANTY; without even the implied warranty of"
		echo "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
		echo "See the GNU General Public License for more details."
		echo ""
		echo "You should have received a copy of the GNU General Public License"
		echo "along with this program; if not, write to the Free Software Foundation,"
		echo "Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA."
		echo ""

};;

esac

exit 0
